package com.learn.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(1)
public class AopDemoProxy {

    /**
     * 目标方法之前执行
     */
    @Before(value = "execution(* com.learn.spring.aop.AopDemo.show(..))")
    public void before() {
        System.out.println("AopDemoProxy 的 before 方法");
    }

    /**
     * 目标方法之后执行，不管成功与否都会通知
     */
    @After(value = "execution(* com.learn.spring.aop.AopDemo.show(..))")
    public void after() {
        System.out.println("AopDemoProxy 的 after 方法");
    }

    /**
     * 目标方法之后执行，遇到异常不会执行
     */
    @AfterReturning(value = "execution(* com.learn.spring.aop.AopDemo.show(..))")
    public void afterReturning() {
        System.out.println("AopDemoProxy 的 afterReturning 方法");
    }

    /**
     * 异常通知，
     */
    @AfterThrowing(value = "execution(* com.learn.spring.aop.AopDemo.show(..))")
    public void afterThrowing() {
        System.out.println("AopDemoProxy 的 afterThrowing 方法");
    }

    /**
     * 环绕通知，在方法之前之后来调用，一定要实用 连接点对象(joinPoint) 来执行 proceed() 否则原始事件不会执行，并且其他通知事件也不会执行
     * 通知嵌套在所有通知最外层，异常会终止方法继续调用，
     * */
    @Around(value = "execution(* com.learn.spring.aop.AopDemo.show(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("AopDemoProxy 的 around 之前方法");
        joinPoint.proceed();
        System.out.println("AopDemoProxy 的 around 之后方法");
    }

}
